import tkinter as tk
from tkinter import messagebox
from win10toast import ToastNotifier
import requests
import os
import socket
import json
import winreg
import sys
import time
import subprocess


def get_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception:
        return None


def save_credentials(user_account, user_password):
    credentials = {'user_account': user_account, 'user_password': user_password}
    file_path = "credentials.json"  # 直接使用相对当前根目录（脚本所在目录）的文件名，不再基于额外目录
    with open(file_path, 'w') as f:
        json.dump(credentials, f)


def load_credentials():
    file_path = "credentials.json"  # 直接使用相对当前根目录（脚本所在目录）的文件名
    if os.path.exists(file_path):
        with open(file_path, 'r') as f:
            return json.load(f)
    return None


def set_startup(enable=True):
    app_name = "SchoolNetworkLogin"
    app_path = os.path.abspath(sys.executable)

    key_val = r'Software\Microsoft\Windows\CurrentVersion\Run'

    try:
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_val, 0, winreg.KEY_ALL_ACCESS)

        if enable:
            winreg.SetValueEx(key, app_name, 0, winreg.REG_SZ, app_path)
        else:
            winreg.DeleteValue(key, app_name)

        winreg.CloseKey(key)
    except Exception as e:
        messagebox.showerror("错误", f"设置开机自启动时出错: {str(e)}")


def create_task_scheduler_task():
    task_name = "SchoolNetworkLoginTask"
    script_path = os.path.abspath(sys.argv[0])
    action = f'schtasks /create /tn "{task_name}" /tr "{script_path}" /sc onlogon /rl highest'

    try:
        subprocess.run(action, shell=True, check=True)
        messagebox.showinfo("成功", "任务计划程序已设置")
    except subprocess.CalledProcessError as e:
        messagebox.showerror("错误", f"设置任务计划程序时出错: {str(e)}")


def auto_login():
    credentials = load_credentials()
    if not credentials:
        show_login_window()
        return

    user_account = credentials['user_account']
    user_password = credentials['user_password']

    login_url = 'http://172.30.255.42'
    sign_in_title = '上网登录页'
    success_indicator = '"result":0'
    logout_title = '注销页'

    icon_path = r'F:\Anaconda\envs\wifi\school_network_login\th_128x128.ico'

    wlan_user_ip = get_ip()
    wlan_ac_ip = '172.30.255.41'

    login_params = {
        'callback': 'dr1003',
        'login_method': '1',
        'user_account': f'%2C0%2C{user_account}',
        'user_password': user_password,
        'wlan_user_ip': wlan_user_ip,
        'wlan_user_ipv6': '',
        'wlan_user_mac': '000000000000',
        'wlan_ac_ip': wlan_ac_ip,
        'wlan_ac_name': '',
        'jsVersion': '4.1.3',
        'terminal_type': '1',
        'lang': 'zh-cn',
        'v': '3569',
        'lang': 'zh'
    }

    try:
        r = requests.get(login_url, timeout=5)
        if logout_title in r.text:
            notify('该设备已经登录', icon_path)
            return

        if sign_in_title in r.text:
            login_response = requests.get(f'{login_url}/eportal/portal/login', params=login_params, timeout=5)

            if success_indicator in login_response.text:
                notify('登录成功', icon_path)
            else:
                notify('登录失败', icon_path)
        else:
            notify('未连接到校园网', icon_path)

    except requests.RequestException as e:
        notify('网络请求异常', icon_path)


def check_network_status():
    while True:
        if get_ip() is None:
            notify('检测到网络断开', r'F:\Anaconda\envs\wifi\school_network_login\th_128x128.ico')
            auto_login()
        time.sleep(30)  # 每隔30秒检查一次网络状态


def show_login_window():
    def on_submit():
        user_account = entry_account.get()
        user_password = entry_password.get()
        if user_account and user_password:
            save_credentials(user_account, user_password)
            if var_startup.get():
                set_startup(True)
                create_task_scheduler_task()
            root.destroy()
            auto_login()
            start_monitoring_thread()
        else:
            messagebox.showwarning("输入错误", "请填写账号和密码")

    root = tk.Tk()
    root.title("校园网登录")
    root.geometry("300x250")

    label_account = tk.Label(root, text="账号:")
    label_account.pack(pady=5)
    entry_account = tk.Entry(root)
    entry_account.pack(pady=5)

    label_password = tk.Label(root, text="密码:")
    label_password.pack(pady=5)
    entry_password = tk.Entry(root, show="*")
    entry_password.pack(pady=5)

    var_startup = tk.BooleanVar()
    checkbutton_startup = tk.Checkbutton(root, text="开机自启动", variable=var_startup)
    checkbutton_startup.pack(pady=5)

    button_submit = tk.Button(root, text="提交", command=on_submit, width=15, height=2)
    button_submit.pack(pady=10)

    root.mainloop()


def notify(title, icon_path):
    toaster = ToastNotifier()
    toaster.show_toast(
        title=title,
        msg='校园网状态',
        icon_path=icon_path,
        duration=5,
        threaded=True
    )


def start_monitoring_thread():
    import threading
    monitoring_thread = threading.Thread(target=check_network_status)
    monitoring_thread.daemon = True
    monitoring_thread.start()


if __name__ == '__main__':
    auto_login()
    start_monitoring_thread()